
import Promise from 'promise-polyfill'
import utils from './utils'
import handleOption from './options'
import Template from './template'
import Timer from './timer'
import EventEmitter from './EventEmitter'
import Controller from './controller'

class LPlayer {
  constructor(options) {
    if (options.openHls) {
      this._flvSupport = false
    } else {
      this._flvSupport = utils.flvCommon.flvSupport
    }

    if (options.video && options.video.watchServer.length > 0) {
      // eslint-disable-next-line no-param-reassign
      options.video.urlArr = utils.loadInitLine(options.video.watchServer, this._flvSupport)
    }

    this.options = handleOption(options)

    this.emitter = new EventEmitter()
    this.timer = new Timer(this)
    this.container = this.options.container
    this.paused = true
    this.template = new Template({
      container: this.container,
      options: this.options
    })
    this.controller = new Controller(this)
    this.video = this.template.video
    this.inWaitingStart = undefined
    this.playingTime = undefined
    this.currentUrl = this.options.video.urlArr[0]
    // 流质量检测
    this.logParams = {
      // 缓冲次数
      bc: 0,
      // video duration
      vd: 0,
      // 播放地址
      playSrc: this.currentUrl,
      // 总共缓冲了多长时间
      bu_acu_t: 0
    }
    this.initVideo()
  }

  initVideo() {
    this.ev = ['play', 'playing', 'pause', 'ended', 'error', 'seeking', 'seeked',
      'timeupdate', 'waiting', 'canplay', 'canplaythrough', 'durationchange', 'volumechange', 'loadeddata'
    ].map((item) => ({
      [item]: `on${item.charAt(0).toUpperCase()}${item.slice(1)}`
    }))
    this.ev.forEach(item => {
      const evName = Object.keys(item)[0]
      const evFunc = this[item[evName]]
      if (evFunc) {
        this.on(evName, evFunc.bind(this))
      }
      this.video.addEventListener(evName, () => {
        this.emitter.trigger(evName)
      })
    })
    if (this._flvSupport) {
      LPlayer.flvPlayer = utils.flvCommon.createFlvPlayer(this.currentUrl, this.video)
      LPlayer.flvPlayer.on('FLV_ERROR', () => {

      })
    }
  }

  x5PlayAuto() {
    Promise.resolve(this.video.play()).catch(err => {
      console.log(err)
    })
    if (utils.isWeixin) {
      const evtFns = []
      try {
        // eslint-disable-next-line no-undef
        utils.wxPlayVideo(this.video)
        return
      } catch (ex) {
        evtFns.push('WeixinJSBridgeReady', () => {
          // eslint-disable-next-line no-undef
          utils.wxPlayVideo(this.video)
          for (let i = 0; i < evtFns.length; i += 2) document.removeEventListener(evtFns[i], evtFns[i + 1], false)
        })
        document.addEventListener('WeixinJSBridgeReady', evtFns[evtFns.length - 1], false)
      }
    }
  }

  play() {
    if (!this.paused || this.template.videoLoad.style.display === 'block') {
      return false
    }
    this.paused = false
    // this.timer.enable('loading')
    this.container.classList.remove('lplayer-paused')
    this.container.classList.add('lplayer-playing')
    if (this.video.paused) {
      if (this._flvSupport) {
        this.flvPlay()
      } else {
        this.hlsPlay()
      }
    }
  }

  hlsPlay() {
    this.x5PlayAuto()
  }

  flvPlay() {
    if (!LPlayer.flvPlayer) {
      LPlayer.flvPlayer = utils.flvCommon.createFlvPlayer(this.currentUrl, this.video)
    }
    LPlayer.flvPlayer.unload()
    LPlayer.flvPlayer.load()
    Promise.resolve(LPlayer.flvPlayer.play()).then(() => {
      LPlayer.flvPlayerPlaying = true
    }).catch(err => {
      console.log(err)
    })
  }

  toggle() {
    if (this.video.paused) {
      this.play()
    }
  }

  on(event, listener) {
    this.emitter.on(event, listener)
  }

  off(event, listener) {
    this.emitter.off(event, listener)
  }

  once(event, listener) {
    this.emitter.once(event, listener)
  }

  onLoadeddata() {
    this.logParams.vd = this.video.duration
  }

  onWaiting() {
    this.logParams.bc++
    this.inWaitingStart = new Date().getTime()
    this.template.videoLoad.style.display = 'block'
    this.playingTime = undefined
  }

  onPlaying() {
    this.template.videoLoad.style.display = 'none'
    if (this.inWaitingStart) {
      this.playingTime = new Date().getTime()
      const pretime = this.playingTime - this.inWaitingStart
      this.logParams.bu_acu_t += pretime
      this.inWaitingStart = undefined
    }
    console.log(this.logParams)
  }
}
LPlayer.flvPlayer = null
LPlayer.flvPlayerPlaying = false
export default LPlayer
